package com.xiaoke.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoke.domain.ResponseResult;
import com.xiaoke.domain.dto.AdminGetArticleListDTO;
import com.xiaoke.domain.dto.CreateArticleDTO;
import com.xiaoke.domain.dto.UpdateArticleDTO;
import com.xiaoke.domain.entity.Article;
import com.xiaoke.domain.entity.TagMiddle;
import com.xiaoke.domain.vo.*;
import com.xiaoke.exception.QueryException;
import com.xiaoke.mapper.ArticleMapper;
import com.xiaoke.service.*;
import com.xiaoke.utils.ArticleUtils;
import com.xiaoke.utils.BeanCopyUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;

import static com.xiaoke.enums.AppHttpCodeEnum.*;
import static com.xiaoke.enums.TagTargetEnum.ARTICLE;


/**
 * 文章表(Article)表后台服务实现类
 *
 * @author xiaoke
 * @since 2023-03-24 14:15:53
 */
@Service("adminArticleService")
public class AdminArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements AdminArticleService {
    @Resource
    ArticleService articleService;

    @Resource
    TagMiddleService tagMiddleService;

    @Resource
    CommonService commonService;

    @Override
    public ResponseResult getArticleList(AdminGetArticleListDTO dto) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.like(dto.getValue() != null,Article::getContent, dto.getValue())
                .eq(dto.getCategoryid() != null,Article::getCategoryid,dto.getCategoryid());

        // TODO 排序,屎一样的代码后面再优化
        if(dto.getSortType() != null && dto.getSort() != null) {
            switch (dto.getSortType()) {
                case TIME:
                    switch (dto.getSort()){
                        case ASC:
                            queryWrapper.orderByAsc(Article::getCreateTime);
                            break;
                        case DESC:
                            queryWrapper.orderByDesc(Article::getCreateTime);
                            break;
                    }
                    break;
                case BROWSE:
                    switch (dto.getSort()){
                        case ASC:
                            queryWrapper.orderByAsc(Article::getBrowse);
                            break;
                        case DESC:
                            queryWrapper.orderByDesc(Article::getBrowse);
                            break;
                    }
                    break;
            }
        }
        // 标签筛选
        if(dto.getTagIdList() != null && !dto.getTagIdList().isEmpty()) {
            Set<Long> byIdsListTargetIds = tagMiddleService.getByIdsListTargetIds(dto.getTagIdList(), ARTICLE);
            queryWrapper.in(!byIdsListTargetIds.isEmpty(),Article::getId,byIdsListTargetIds);
        }

        Page<Article> articlePage = new Page<>(dto.getPageNum(), dto.getPageSize());

        Page<Article> page = page(articlePage, queryWrapper);

        List<Article> articleList = page.getRecords();
        // 设置分类名称
        articleService.setArticleListCategoryName(articleList);
        // 设置标签列表
        articleService.setArticleListTagList(articleList);

        List<AdminGetArticleListVo> adminGetArticleListVos = BeanCopyUtils.copyBeanList(articleList, AdminGetArticleListVo.class);
        PageVo pageVo = new PageVo(adminGetArticleListVos,articlePage.getTotal());

        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult getArticle(Long id) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Article::getId,id);
        Article article = articleService.findArticle(queryWrapper);
        AdminGetArticleVo adminGetArticleVo = BeanCopyUtils.copyBean(article, AdminGetArticleVo.class);

        return ResponseResult.okResult(adminGetArticleVo);
    }

    @Override
    public ResponseResult createArticle(CreateArticleDTO dto) {
        Article article = article(dto);
          // 新增文章
        save(article);
        // 保存标签
        setArticleTagList(dto.getTagIdList(),article.getId());
        return ResponseResult.okResult(article.getId(),CREATE_SUCCESS);
    }
    @Override
    public ResponseResult delArticle(Long id) {
        boolean del = removeById(id);
        if(!del) {
            return ResponseResult.errorResult(DEL_ERROR);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult updateArticle(UpdateArticleDTO dto, String id) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(Article::getId,id);
        Article oldArticle = getOne(queryWrapper);
        // 文章不存在
        if(oldArticle == null) {
            throw  new QueryException();
        }
        // 修改文章
        Article newArticle = article(dto);
        BeanCopyUtils.copyNonNullProperties(newArticle,oldArticle);
        update(oldArticle,queryWrapper);

        // 修改标签
        LambdaQueryWrapper<TagMiddle> tagQueryWrapper = new LambdaQueryWrapper<>();
        tagQueryWrapper.eq(TagMiddle::getTargetId,oldArticle.getId());
        // 把原来的标签全部删除
        tagMiddleService.remove(tagQueryWrapper);
        setArticleTagList(dto.getTagIdList(),oldArticle.getId());

        return ResponseResult.okResult(MODIFY_SUCCESS);
    }

    /**
     *  保存标签
     * @param ids 标签ID集合
     * @param aid 文章ID
     */
    public void setArticleTagList (Set<Long> ids,Long aid) {
        if(ids != null && !ids.isEmpty()) {
            for (Long id : ids) {
                TagMiddle tagMiddle = new TagMiddle();
                tagMiddle.setLabelId(id);
                tagMiddle.setTargetId(aid);
                tagMiddle.setTargetCategory(ARTICLE.getCode());
                tagMiddleService.save(tagMiddle);
            }
        }
    }

    /**
     * 文章实体赋值
     * @param dto 文章DTO
     * @return 文章实体
     */
    public Article article(CreateArticleDTO dto) {
        Article article = new Article();
        article.setTitle(dto.getTitle());
        article.setUserId(commonService.getUserId());
        article.setCategoryid(dto.getCategoryid());
        article.setContent(dto.getContent());
        article.setDigest(dto.getDigest() == null ?  ArticleUtils.getDigest(dto.getContent()) : dto.getDigest());
        article.setStatus(String.valueOf(dto.getStatus()));
        article.setIsTop(String.valueOf(dto.getIsTop()));
        return article;
    }
}
